package com.fxm.service.impl;

import cn.hutool.core.lang.Dict;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.json.JSONUtil;
import com.aliyuncs.CommonRequest;
import com.aliyuncs.CommonResponse;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.exceptions.ServerException;
import com.aliyuncs.http.MethodType;
import com.aliyuncs.profile.DefaultProfile;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fxm.constant.RedisConstants;
import com.fxm.dao.UserMapper;
import com.fxm.domain.Rule;
import com.fxm.domain.User;
import com.fxm.returns.RespCode;
import com.fxm.returns.RespEntity;
import com.fxm.returns.RespTable;
import com.fxm.service.RuleService;
import com.fxm.service.UserService;
import com.fxm.utils.RedisUtil;
import com.fxm.vo.MapVO;
import com.fxm.vo.param.LoginParam;
import com.fxm.vo.param.UserParam;
import com.fxm.vo.result.SexResult;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * <p>
 * 用户 服务实现类
 * </p>
 *
 * @author fxm
 * @since 2021-02-04
 */
@Slf4j
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

    @Autowired
    private RedisUtil redisUtil;

    @Autowired
    private RuleService ruleService;

    @Value("${aliyun.sms.url}")
    private String url;

    @Value("${aliyun.sms.accessKeyId}")
    private String accessKeyId;

    @Value("${aliyun.sms.accessSecret}")
    private String accessSecret;

    @Override
    public RespEntity<User> login(LoginParam loginParam) {
        QueryWrapper<User> queryWrapper = new QueryWrapper();
        //按照账号和密码查询用户信息
        queryWrapper.lambda().eq(User::getUsername, loginParam.getUsername())
                .eq(User::getPassword, loginParam.getPassword());

        User user = baseMapper.selectOne(queryWrapper);
        if (Objects.isNull(user)) {
            return new RespEntity(RespCode.NOT_FOUND);
        }
        return new RespEntity(RespCode.SUCCESS, user);
    }

    @Override
    public RespTable<List<User>> queryAllUser(UserParam userParam) {
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        if (Objects.nonNull(userParam.getColumn()) && Objects.nonNull(userParam.getValue())) {
            queryWrapper.like(userParam.getColumn(), userParam.getValue());
        }
        queryWrapper.lambda().eq(User::getDeleted, 0);
        IPage<User> iPage = new Page<>(userParam.getPage(), userParam.getLimit());
        IPage<User> page = super.page(iPage, queryWrapper);
        return new RespTable(RespCode.OK, page.getRecords(), page.getTotal());
    }

    @Override
    public RespEntity<List<MapVO>> chinaMap(String beginDate, String endDate) {
        List<MapVO> mapVOList = baseMapper.chinaMap(beginDate, endDate);
        return new RespEntity(RespCode.SUCCESS, mapVOList);
    }

    @Override
    public RespEntity<List<MapVO>> provinceMap(String province, String beginDate, String endDate) {
        List<MapVO> mapVOList = baseMapper.provinceMap(province, beginDate, endDate);
        return new RespEntity(RespCode.SUCCESS, mapVOList);
    }

    @Override
    public RespEntity<Integer> sendMsg(String mobile) {
        //随机生成6位数字验证码
        String code = RandomUtil.randomNumbers(6);
        //发送短信验证码
        String ok = send(mobile, code);
        if (StringUtils.isBlank(ok)) {
            return new RespEntity(RespCode.NOT_FOUND);
        }
        //获取短信验证码 间隔时间
        Integer time = 60;
        //code保存redis 并设置过期时间
        redisUtil.hset(RedisConstants.key.SMS, mobile, code, time);

        return new RespEntity(RespCode.SUCCESS, time);
    }

    /**
     * 发送短信验证码
     * @param mobile
     * @return
     */
    private String send(String mobile, String code) {
        Dict dict = Dict.create().set("code", code);

        DefaultProfile profile = DefaultProfile.getProfile("cn-hangzhou", accessKeyId, accessSecret);
        IAcsClient client = new DefaultAcsClient(profile);

        CommonRequest request = new CommonRequest();
        request.setSysMethod(MethodType.POST);
        request.setSysDomain("dysmsapi.aliyuncs.com");
        request.setSysVersion("2017-05-25");
        request.setSysAction("SendSms");
        request.putQueryParameter("RegionId", "cn-hangzhou");
        request.putQueryParameter("PhoneNumbers", mobile);
        request.putQueryParameter("SignName", "丸哥提醒");
        request.putQueryParameter("TemplateCode", "SMS_201681236");
        request.putQueryParameter("TemplateParam", JSONUtil.toJsonStr(dict));
        try {
            CommonResponse response = client.getCommonResponse(request);
            log.info("短信验证码发送结果，response={}", response.getData());
            Map<String, String> respMap = JSONUtil.toBean(response.getData(), Map.class);
            if (StringUtils.equals(respMap.get("Code"), "OK")) {
                return "OK";
            }
        } catch (ServerException e) {
            e.printStackTrace();
        } catch (ClientException e) {
            e.printStackTrace();
        }
        return null;
    }

    @Override
    public RespEntity<List<User>> queryUserByIds(Integer[] ids) {
        List<User> userList = baseMapper.selectBatchIds(Arrays.asList(ids));
        return new RespEntity(RespCode.SUCCESS, userList);
    }

    @Override
    public RespEntity<List<User>> allUser() {
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(User::getDeleted, 0);
        List<User> userList = baseMapper.selectList(queryWrapper);
        return new RespEntity(RespCode.SUCCESS, userList);
    }

    @Override
    public RespEntity banUser(Integer id) {
        User user = baseMapper.selectById(id);
        user.setDeleted(1);
        //用户表 封禁用户
        baseMapper.updateById(user);

        QueryWrapper<Rule> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(Rule::getOpenid, user.getOpenid());
        Rule rule = ruleService.getOne(queryWrapper);
        rule.setDeleted(1);
        //答题规则表 封禁用户
        ruleService.updateById(rule);

        return new RespEntity(RespCode.SUCCESS);
    }

    @Override
    public RespEntity<SexResult> querySexCount() {
        QueryWrapper<User> queryWrapperOther = new QueryWrapper<>();
        queryWrapperOther.lambda().eq(User::getDeleted, 0).eq(User::getSex, 0);
        Integer otherCount = baseMapper.selectCount(queryWrapperOther);

        QueryWrapper<User> queryWrapperMan = new QueryWrapper<>();
        queryWrapperMan.lambda().eq(User::getDeleted, 0).eq(User::getSex, 1);
        Integer manCount = baseMapper.selectCount(queryWrapperMan);

        QueryWrapper<User> queryWrapperWomen = new QueryWrapper<>();
        queryWrapperWomen.lambda().eq(User::getDeleted, 0).eq(User::getSex, 2);
        Integer womenCount = baseMapper.selectCount(queryWrapperWomen);

        return new RespEntity(RespCode.SUCCESS, new SexResult(manCount, womenCount, otherCount));
    }

    @Override
    public RespTable<List<User>> blackList(UserParam userParam) {
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        if (Objects.nonNull(userParam.getColumn()) && Objects.nonNull(userParam.getValue())) {
            queryWrapper.like(userParam.getColumn(), userParam.getValue());
        }
        queryWrapper.lambda().eq(User::getDeleted, 1);
        IPage<User> iPage = new Page<>(userParam.getPage(), userParam.getLimit());
        IPage<User> page = super.page(iPage, queryWrapper);
        return new RespTable(RespCode.OK, page.getRecords(), page.getTotal());
    }

    @Override
    public RespEntity unseal(Integer id) {
        User user = baseMapper.selectById(id);
        user.setDeleted(0);
        //用户表 解封用户
        baseMapper.updateById(user);

        QueryWrapper<Rule> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(Rule::getOpenid, user.getOpenid());
        Rule rule = ruleService.getOne(queryWrapper);
        rule.setDeleted(0);
        //答题规则表 解封用户
        ruleService.updateById(rule);
        return new RespEntity(RespCode.SUCCESS);
    }

}
